import sdk from '../core';
import { config, configKey } from '../config';
import { ItemType } from '../shared/face/enums';
import { TaskService } from './TaskService';
import { TaskTargetType } from '../core/rpg/types/task';
import { asyncStaticToInstance, LegacyServiceAdapter } from './base/LegacyServiceAdapter';
import { ModernSignService } from './ModernSignService';

export class SignService {

    /**
     * 检查是否可以签到
     * @param lastSignDate 上次签到时间
     * @returns 是否可以签到
     */
    @asyncStaticToInstance(ModernSignService)
    static canSign(lastSignDate?: string): boolean {
        if (!lastSignDate) return true;
        
        const lastSign = new Date(lastSignDate);
        const now = new Date();
        
        // 获取今天的凌晨4点时间
        const today4am = new Date(now);
        today4am.setHours(4, 0, 0, 0);
        
        // 如果上次签到时间在今天凌晨4点之前，则可以签到
        return lastSign < today4am;
    }

    /**
     * 处理签到逻辑
     * @param player 玩家对象
     * @returns 签到结果
     */
    @asyncStaticToInstance(ModernSignService)
    static async sign(player: any): Promise<{
        success: boolean;
        message: string;
        rewards?: any[];
        signData: any;
        completedTasks?: any[];
    }> {
        const signComponent = player.getComponent('sign') as any;
        if (!signComponent) {
            return {
                success: false,
                message: '签到组件未找到',
                signData: {}
            };
        }

        const signData = signComponent.signData || {};
        const lastSignDate = signData.lastSignDate;
        
        // 检查是否可以签到
        if (!this.canSign(lastSignDate)) {
            return {
                success: false,
                message: '今天已经签到过了，明天再来吧！',
                signData: signData
            };
        }

        const now = new Date();
        const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
        
        // 计算连续签到天数
        let consecutiveDays = 1;
        if (lastSignDate) {
            const lastSign = new Date(lastSignDate);
            const lastSignDay = new Date(lastSign.getFullYear(), lastSign.getMonth(), lastSign.getDate());
            
            // 如果上次签到是昨天，则连续签到天数+1
            if (lastSignDay.getTime() === yesterday.getTime()) {
                consecutiveDays = (signData.consecutiveDays || 0) + 1;
            } else if (lastSignDay.getTime() < yesterday.getTime()) {
                // 如果超过一天没签到，重置连续签到天数
                consecutiveDays = 1;
            } else {
                // 如果上次签到是今天，不应该到这里，但为了安全起见
                return {
                    success: false,
                    message: '今天已经签到过了',
                    signData: signData
                };
            }
        }

        // 更新签到数据
        const newSignData = {
            lastSignDate: now.toISOString(),
            consecutiveDays: consecutiveDays,
            totalSignDays: (signData.totalSignDays || 0) + 1
        };

        // 获取奖励
        const rewards = this.getSignRewards(consecutiveDays);
        
        // 发放奖励
        if (rewards.length > 0) {
            const bagComponent = player.getComponent('bag') as any;
            if (bagComponent) {
                rewards.forEach(reward => {
                    bagComponent.addItem(reward);
                });
            }
        }

        // 更新组件数据
        signComponent.signData = newSignData;

        // 更新任务进度（包括个人任务和全服任务）
        const taskResult = await TaskService.updateTaskProgress(player, TaskTargetType.签到);

        return {
            success: true,
            message: `签到成功!`,
            rewards: rewards,
            signData: newSignData,
            completedTasks: taskResult.completedTasks
        };
    }

    /**
     * 获取签到奖励
     * @param consecutiveDays 连续签到天数
     * @returns 奖励数组
     */
    private static getSignRewards(consecutiveDays: number): any[] {
        // 查找对应的奖励配置
        const signRewards = config.get(configKey.配置_签到奖励表) as Map<string,any>;
        const rewardConfig = signRewards.get(consecutiveDays.toString());
        if (!rewardConfig) {
            // 如果超过配置的最大天数，使用最大天数的奖励
            const maxConfig = signRewards.get(signRewards.size.toString());
            return this.generateRewards(maxConfig.rewards);
        }
        
        return this.generateRewards(rewardConfig.rewards);
    }

    /**
     * 生成奖励道具
     * @param rewardConfigs 奖励配置
     * @returns 奖励道具数组
     */
    private static generateRewards(rewardConfigs: any[]): any[] {
        const rewards: any[] = [];
        const rewardMap = new Map<string, any>(); // 用于合并相同类型的奖励
        
        rewardConfigs.forEach(config => {
            const count = Math.floor(Math.random() * (Number(config.max) - Number(config.min) + 1)) + Number(config.min);
            const key = `${config.type}_${config.id}`;
            
            if (rewardMap.has(key)) {
                // 合并相同类型的奖励
                rewardMap.get(key).count += count;
            } else {
                // 创建新的奖励道具
                const prop = sdk.prop.createProp({
                    type: config.type,
                    id: config.id,
                    count: count
                });
                rewardMap.set(key, prop);
            }
        });
        
        // 将合并后的奖励添加到结果数组
        rewardMap.forEach(prop => {
            rewards.push(prop);
        });
        
        return rewards;
    }

    /**
     * 获取签到状态
     * @param player 玩家对象
     * @returns 签到状态信息
     */
    @asyncStaticToInstance(ModernSignService)
    static getSignStatus(player: any): {
        canSign: boolean;
        consecutiveDays: number;
        totalSignDays: number;
        lastSignDate?: string;
    } {
        const signComponent = player.getComponent('sign') as any;
        if (!signComponent) {
            return {
                canSign: false,
                consecutiveDays: 0,
                totalSignDays: 0
            };
        }

        const signData = signComponent.signData || {};
        const canSign = this.canSign(signData.lastSignDate);

        return {
            canSign: canSign,
            consecutiveDays: signData.consecutiveDays || 0,
            totalSignDays: signData.totalSignDays || 0,
            lastSignDate: signData.lastSignDate
        };
    }
}
